package org.jwt.oauth.security;

import java.util.List;

import org.jwt.oauth.constant.ConstantAttribute;
import org.jwt.oauth.properties.FusionTokenProperties;
import org.jwt.oauth.tools.ConcurrentTools;
import org.jwt.oauth.tools.NotLoginAuthUrlTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
@EnableResourceServer
public class FusionTokenClientConfig extends ResourceServerConfigurerAdapter {

	@Autowired
	private FusionTokenProperties tokenProperties;

	@Override
	public void configure(HttpSecurity http) throws Exception {
		// 设置请求拦截
		ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http
				.authorizeRequests();
		//根据配置文件获取不需要校验的请求地址
		String[] noRelease = tokenProperties.getNoRelease();
		if (noRelease != null && noRelease.length > 0) {
			for (String noReleaseUrl : noRelease) {
				if (noReleaseUrl != null && !noReleaseUrl.equalsIgnoreCase(ConstantAttribute.NULL) && noReleaseUrl.length() > 0) {
					authorizeRequests.antMatchers(noReleaseUrl).permitAll();
				}
			}
		}
		//根据注解获取不需要校验的请求地址
		List<String> notAuthUrlList = NotLoginAuthUrlTools.getNotAuthUrlList(tokenProperties.getMethodsPackage());
		if(notAuthUrlList!=null && notAuthUrlList.size() > 0) {
			for (String notAuthUrl : notAuthUrlList) {
				authorizeRequests.antMatchers(notAuthUrl).permitAll();
			}
			//保存到全局变量线程里面
			ConcurrentTools.getConcurrentHashMap().put(ConstantAttribute.NOT_AUTH_URL_LIST,notAuthUrlList);
		}
		authorizeRequests.antMatchers(HttpMethod.OPTIONS).permitAll();
		// 设置拦截所有的请求
		authorizeRequests.anyRequest().authenticated().and().csrf().disable();
	}

	@Override
	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
		resources.tokenStore(jwtTokenStore());
	}
	
	@Bean
	public TokenStore jwtTokenStore() {
		return new JwtTokenStore(jwtAccessTokenConverter());
	}
	
	@Bean
	public JwtAccessTokenConverter jwtAccessTokenConverter() {
		JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter() {
			@Override
			public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
				OAuth2AccessToken enhancedToken = super.enhance(accessToken, authentication);
				return enhancedToken;
			}
		};
		jwtAccessTokenConverter.setSigningKey(tokenProperties.getUsername());
		return jwtAccessTokenConverter;
	}
	
	@Bean
	@ConfigurationProperties("spring.fusion.token")
	@ConditionalOnMissingBean(FusionTokenProperties.class)
	public FusionTokenProperties fusionTokenProperties() {
		return new FusionTokenProperties();
	}

}
